<?php

namespace Simanx\Spes\Module;

class Module
{
    /**
     * @var string 模块名
     */
    private string $name;

    /**
     * @var string 模块根目录
     */
    private string $rootPath;

    /**
     * @var string 模块根命名空间
     */
    private string $rootNameSpace;

    /**
     * @var string[] 模块包含的各种文件夹类型
     */
    private static array $dirs = [];

    public function __construct(string $name)
    {
        $moduleRoot = config('spes.module.root', 'App\\Modules');
        $this->name = $name;
        $this->rootPath = $moduleRoot . DIRECTORY_SEPARATOR . $name;
        $this->rootNameSpace = sprintf('%s\\%s\\',
            config('spes.module.namespace', 'App\\Modules'),
            ucfirst($name)
        );
    }

    /**
     * 获取对应类型文件夹对应的命名空间
     * @param string|null $type 文件夹类型,默认获取根命名空间
     * @return string|null
     */
    public function getNamespace(string|null $type = null): string|null
    {
        if (is_null($type)) {
            return $this->rootNameSpace;
        }

        if (!isset(static::$dirs[$type])) {
            return null;
        }

        return $this->rootNameSpace . '\\' . ucfirst(static::dir($type));
    }

    /**
     * 获取对应类型文件夹的路径
     * @param string|null $type 文件夹类型,默认获取根文路径
     * @return string|null
     */
    public function path(string|null $type = null): string|null
    {
        if (is_null($type)) {
            return $this->rootPath;
        }

        if (static::dir($type) === null) {
            return null;
        }

        return $this->rootPath . DIRECTORY_SEPARATOR . static::dir($type);
    }

    /**
     * 获取所有类型文件夹路径
     * @return array
     */
    public function allPath()
    {
        $paths = [];
        foreach (static::dirs() as $type => $dir) {
            $paths[$type] = $this->path($type);
        }

        return $paths;
    }

    /**
     * 模块名
     * @return string
     */
    public function name(): string
    {
        return $this->name;
    }

    /**
     * 文件夹映射
     * @return string[]
     */
    public static function dirs()
    {
        if (static::$dirs) {
            return static::$dirs;
        }

        $dirs = config('spes.module.dirs', []);
        foreach ($dirs as $key => $dir) {
            static::$dirs[$key] = $dir;
        }

        return static::$dirs;
    }

    /**
     * 获取文件夹类型映射
     * @param string $type
     * @return string
     */
    public static function dir(string $type)
    {
        return static::dirs()[$type];
    }
}